#include<string>
#include<vector>
#include<array>
#include<unordered_map>
#include<algorithm>
#include<limits>
#include <stack>
#include<iostream>
#include<sstream>
#include<deque>
#define MOD 1000000007
class UnionFind {
private:
    std::vector<int> parent;  // 存储每个元素的父节点
    std::vector<int> rank;    // 存储每个集合的秩（用于按秩合并）
    int count;                // 元素的总数量

public:
    // 构造函数，初始化并查集
    UnionFind(int size) : count(size) {
        parent.resize(size);
        rank.resize(size, 0);
        
        // 初始化每个元素的父节点为自身
        for (int i = 0; i < size; ++i) {
            parent[i] = i;
        }
    }
    
    // 查找元素的根节点，使用路径压缩优化
    int find(int x) {
        // 如果x不是根节点，递归查找其父节点的根节点，并将x直接连接到根节点（路径压缩）
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    
    // 合并两个元素所在的集合，使用按秩合并优化
    bool unite(int x, int y) {
        // 查找两个元素的根节点
        int rootX = find(x);
        int rootY = find(y);
        
        // 如果已经在同一个集合中，则不需要合并
        if (rootX == rootY) {
            return false;
        }
        
        // 按秩合并：将秩较小的树合并到秩较大的树的根节点下
        if (rank[rootX] < rank[rootY]) {
            parent[rootX] = rootY;
        } else {
            parent[rootY] = rootX;
            // 如果秩相等，合并后秩加1
            if (rank[rootX] == rank[rootY]) {
                rank[rootX]++;
            }
        }
        return true;
    }
    
    // 判断两个元素是否在同一个集合中
    bool isConnected(int x, int y) {
        return find(x) == find(y);
    }
    
    // 获取当前集合的数量
    int getCount() const {
        return count;
    }
};
class Solution
{
public:
    std::vector<bool> distanceLimitedPathsExist(int n, std::vector<std::vector<int>>& edgeList,
                                                std::vector<std::vector<int>>& queries)
    {
        int qn = queries.size();
        int en = edgeList.size();
        for (int i = 0; i < qn; i++)
        {
            queries[i].push_back(i);
        }
        std::sort(edgeList.begin(), edgeList.end(), [](const std::vector<int>& a, const std::vector<int>& b)
        {
            return a[2] < b[2];
        });
        std::sort(queries.begin(), queries.end(),[](const std::vector<int>& a, const std::vector<int>& b)
        {
            return a[2]<b[2];
        });
        UnionFind unionFind(n);
        std::vector<bool> visited(qn, false);
        int l = 0;
        
        for (int i = 0; i < qn; i++)
        {
            for (;l<en&&edgeList[l][2]<queries[i][2];l++)
            {
                if (unionFind.unite(edgeList[l][0],edgeList[l][1]))
                {
                    
                }
            }
            if (unionFind.isConnected(queries[i][0], queries[i][1]))
            {
                visited[queries[i][3]] = true;
            }
        }
        return visited;
    }
};
